<template>
  <div class="pull-refresh-container" ref="containerRef">
    <div
      class="pull-refresh-content"
      :style="{ transform: `translateY(${translateY}px)` }"
      @touchstart="handleTouchStart"
      @touchmove="handleTouchMove"
      @touchend="handleTouchEnd"
    >
      <!-- 下拉提示 - 只在有下拉动作时显示 -->
      <div
        v-if="translateY > 0"
        class="pull-refresh-indicator"
        :class="{ 'refreshing': isRefreshing }"
      >
        <n-icon v-if="!isRefreshing" size="20" :class="{ 'rotate': translateY >= props.threshold }">
          <ArrowDownIcon />
        </n-icon>
        <n-spin v-else size="small" />
        <div class="refresh-text">
          <div>{{ refreshText }}</div>
          <div v-if="lastRefreshTime" class="last-refresh-time">
            上次刷新时间: {{ formatTime(lastRefreshTime) }}
          </div>
        </div>
      </div>

      <!-- 内容区域 -->
      <div class="pull-refresh-body">
        <slot />
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue'
import { ArrowDown as ArrowDownIcon } from '@vicons/ionicons5'
import dayjs from 'dayjs'

interface Props {
  threshold?: number // 触发刷新的阈值
  maxPullDistance?: number // 最大下拉距离
}

const props = withDefaults(defineProps<Props>(), {
  threshold: 80,
  maxPullDistance: 120
})

const emit = defineEmits<{
  refresh: []
}>()

const containerRef = ref<HTMLElement>()
const translateY = ref(0)
const startY = ref(0)
const isRefreshing = ref(false)
const lastRefreshTime = ref<Date | null>(null)

const refreshText = computed(() => {
  if (isRefreshing.value) return '正在刷新...'
  if (translateY.value >= props.threshold) return '松开刷新'
  return '下拉刷新'
})

const formatTime = (time: Date) => {
  return dayjs(time).format('MM-DD HH:mm:ss')
}

const handleTouchStart = (e: TouchEvent) => {
  if (isRefreshing.value) return

  const touch = e.touches[0]
  startY.value = touch.clientY
}

const handleTouchMove = (e: TouchEvent) => {
  if (isRefreshing.value) return

  const touch = e.touches[0]
  const deltaY = touch.clientY - startY.value

  // 只有在顶部且向下滑动时才处理
  if (deltaY > 0 && window.scrollY === 0) {
    e.preventDefault()
    translateY.value = Math.min(deltaY * 0.5, props.maxPullDistance)
  }
}

const handleTouchEnd = async () => {
  if (isRefreshing.value) return

  if (translateY.value >= props.threshold) {
    // 触发刷新
    isRefreshing.value = true
    translateY.value = props.threshold

    try {
      await emit('refresh')
      // 更新最后刷新时间
      lastRefreshTime.value = new Date()
    } finally {
      isRefreshing.value = false
      translateY.value = 0
    }
  } else {
    // 回弹
    translateY.value = 0
  }
}
</script>

<style scoped>
.pull-refresh-container {
  overflow: hidden;
  position: relative;
}

.pull-refresh-content {
  transition: transform 0.3s ease;
}

.pull-refresh-indicator {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 60px;
  color: #666;
  font-size: 14px;
  gap: 8px;
  background: rgba(255, 255, 255, 0.95);
  backdrop-filter: blur(10px);
}

.pull-refresh-indicator.refreshing {
  color: #18a058;
}

.refresh-text {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
}

.last-refresh-time {
  font-size: 12px;
  color: #999;
}

.pull-refresh-body {
  min-height: 100vh;
}

.rotate {
  transform: rotate(180deg);
  transition: transform 0.3s ease;
}
</style>
